home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / APPLICATIONMANAGER.PY < prev    next >
Encoding:
Python Source  |  2000-08-25  |  14.6 KB  |  452 lines

  1. ##############################################################################
  2. # Zope Public License (ZPL) Version 1.0
  3. # -------------------------------------
  4. # Copyright (c) Digital Creations.  All rights reserved.
  5. # This license has been certified as Open Source(tm).
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions are
  8. # met:
  9. # 1. Redistributions in source code must retain the above copyright
  10. #    notice, this list of conditions, and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. #    notice, this list of conditions, and the following disclaimer in
  13. #    the documentation and/or other materials provided with the
  14. #    distribution.
  15. # 3. Digital Creations requests that attribution be given to Zope
  16. #    in any manner possible. Zope includes a "Powered by Zope"
  17. #    button that is installed by default. While it is not a license
  18. #    violation to remove this button, it is requested that the
  19. #    attribution remain. A significant investment has been put
  20. #    into Zope, and this effort will continue if the Zope community
  21. #    continues to grow. This is one way to assure that growth.
  22. # 4. All advertising materials and documentation mentioning
  23. #    features derived from or use of this software must display
  24. #    the following acknowledgement:
  25. #      "This product includes software developed by Digital Creations
  26. #      for use in the Z Object Publishing Environment
  27. #      (http://www.zope.org/)."
  28. #    In the event that the product being advertised includes an
  29. #    intact Zope distribution (with copyright and license included)
  30. #    then this clause is waived.
  31. # 5. Names associated with Zope or Digital Creations must not be used to
  32. #    endorse or promote products derived from this software without
  33. #    prior written permission from Digital Creations.
  34. # 6. Modified redistributions of any form whatsoever must retain
  35. #    the following acknowledgment:
  36. #      "This product includes software developed by Digital Creations
  37. #      for use in the Z Object Publishing Environment
  38. #      (http://www.zope.org/)."
  39. #    Intact (re-)distributions of any official Zope release do not
  40. #    require an external acknowledgement.
  41. # 7. Modifications are encouraged but must be packaged separately as
  42. #    patches to official Zope releases.  Distributions that do not
  43. #    clearly separate the patches from the original work must be clearly
  44. #    labeled as unofficial distributions.  Modifications which do not
  45. #    carry the name Zope may be packaged in any form, as long as they
  46. #    conform to all of the clauses above.
  47. # Disclaimer
  48. #   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
  49. #   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  50. #   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  51. #   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
  52. #   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  53. #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  54. #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  55. #   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  56. #   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  57. #   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  58. #   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  59. #   SUCH DAMAGE.
  60. # This software consists of contributions made by Digital Creations and
  61. # many individuals on behalf of Digital Creations.  Specific
  62. # attributions are listed in the accompanying credits file.
  63. ##############################################################################
  64. __doc__="""System management components"""
  65. __version__='$Revision: 1.60.12.3 $'[11:-2]
  66.  
  67.  
  68. import sys,os,time,string,Globals, Acquisition, os, Undo
  69. from Globals import HTMLFile
  70. from OFS.ObjectManager import ObjectManager
  71. from OFS.Folder import Folder
  72. from CacheManager import CacheManager
  73. from DateTime.DateTime import DateTime
  74. from OFS import SimpleItem
  75. from App.Dialogs import MessageDialog
  76. from Product import ProductFolder
  77. from version_txt import version_txt
  78. from cStringIO import StringIO
  79.  
  80. try: import thread
  81. except: get_ident=lambda: 0
  82. else: get_ident=thread.get_ident
  83.  
  84. class Fake:
  85.     def locked_in_version(self): return 0
  86.  
  87. class DatabaseManager(Fake, SimpleItem.Item, Acquisition.Implicit):
  88.     """Database management"""
  89.     manage=manage_main=HTMLFile('dbMain', globals())
  90.     id        ='DatabaseManagement'
  91.     name=title='Database Management'
  92.     meta_type ='Database Management'
  93.     icon='p_/DatabaseManagement_icon'
  94.  
  95.     manage_options=(
  96.         (
  97.         {'label':'Database', 'action':'manage_main',
  98.          'help':('OFSP','Database-Management_Database.stx')},
  99.         {'label':'Cache Parameters', 'action':'manage_cacheParameters',
  100.          'help':('OFSP','Database-Management_Cache-Parameters.stx')},
  101.         {'label':'Flush Cache', 'action':'manage_cacheGC',
  102.          'help':('OFSP','Database-Management_Flush-Cache.stx')},
  103.         )
  104.         )
  105.  
  106. Globals.default__class_init__(DatabaseManager)
  107.  
  108. class VersionManager(Fake, SimpleItem.Item, Acquisition.Implicit):
  109.     """Version management"""
  110.     manage=manage_main=HTMLFile('versionManager', globals())
  111.     id        ='Versions'
  112.     name=title='Version Management'
  113.     meta_type ='Version Management'
  114.     icon='p_/VersionManagement_icon'
  115.  
  116.     manage_options=(
  117.         (
  118.         {'label':'Version', 'action':'manage_main',
  119.          'help':('OFSP','Version-Management_Version.stx')},
  120.         )
  121.         )
  122.         
  123. Globals.default__class_init__(VersionManager)
  124.  
  125.  
  126.  
  127.  
  128. # refcount snapshot info
  129. _v_rcs=None
  130. _v_rst=None
  131.  
  132. class DebugManager(Fake, SimpleItem.Item, Acquisition.Implicit):
  133.     """Debug and profiling information"""
  134.     manage=manage_main=HTMLFile('debug', globals())
  135.     id        ='DebugInfo'
  136.     name=title='Debug Information'
  137.     meta_type = name
  138.     icon='p_/DebugManager_icon'
  139.  
  140.     manage_options=(
  141.         (  {'label':'Debugging Info', 'action':'manage_main',
  142.             'help':('OFSP','Debug-Information_Debug.stx')},
  143.            {'label':'Profiling', 'action':'manage_profile',
  144.             'help':('OFSP','Debug-Information_Profile.stx')},
  145.            )
  146.         )
  147.  
  148.     manage_debug=HTMLFile('debug', globals())
  149.     
  150.     def refcount(self, n=None, t=(type(Fake), type(Acquisition.Implicit))):
  151.         # return class reference info
  152.         dict={}
  153.         for m in sys.modules.values():
  154.             for sym in dir(m):
  155.                 ob=getattr(m, sym)
  156.                 if type(ob) in t:
  157.                     dict[ob]=sys.getrefcount(ob)
  158.         pairs=[]
  159.         append=pairs.append
  160.         for ob, v in dict.items():
  161.             if hasattr(ob, '__module__'):
  162.                 name='%s.%s' % (ob.__module__, ob.__name__)
  163.             else: name='%s' % ob.__name__
  164.             append((v, name))
  165.         pairs.sort()
  166.         pairs.reverse()
  167.         if n is not None:
  168.             pairs=pairs[:n]
  169.         return pairs
  170.  
  171.     def refdict(self):
  172.         rc=self.refcount()
  173.         dict={}
  174.         for v, n in rc:
  175.             dict[n]=v
  176.         return dict
  177.  
  178.     def rcsnapshot(self):
  179.         global _v_rcs
  180.         global _v_rst
  181.         _v_rcs=self.refdict()
  182.         _v_rst=DateTime()
  183.  
  184.     def rcdate(self):
  185.         return _v_rst
  186.  
  187.     def rcdeltas(self):
  188.         if _v_rcs is None:
  189.             self.rcsnapshot()
  190.         nc=self.refdict()
  191.         rc=_v_rcs
  192.         rd=[]
  193.         for n, c in nc.items():
  194.             try:
  195.                 prev=rc[n]
  196.                 if c > prev:
  197.                     rd.append( (c - prev, (c, prev, n)) )
  198.             except: pass
  199.         rd.sort()
  200.         rd.reverse()
  201.         return map(lambda n: {'name': n[1][2],
  202.                               'delta': n[0],
  203.                               'pc': n[1][1],
  204.                               'rc': n[1][0]}, rd)
  205.  
  206.     def dbconnections(self):
  207.         return Globals.DB.connectionDebugInfo()
  208.  
  209.  
  210.     # Profiling support
  211.  
  212.     manage_profile=HTMLFile('profile', globals())
  213.  
  214.     def manage_profile_stats(self, sort='time', limit=200):
  215.         """Return profile data if available"""
  216.         stats=getattr(sys, '_ps_', None)
  217.         if stats is None:
  218.             return None
  219.         output=StringIO()
  220.         stdout=sys.stdout
  221.         sys.stdout=output
  222.         stats.strip_dirs().sort_stats(sort).print_stats(limit)
  223.         sys.stdout.flush()
  224.         sys.stdout=stdout
  225.         return output.getvalue()
  226.  
  227. Globals.default__class_init__(DebugManager)
  228.  
  229.  
  230.  
  231.  
  232. class ApplicationManager(Folder,CacheManager):
  233.     """System management"""
  234.  
  235.     __roles__=('Manager',)
  236.     isPrincipiaFolderish=1
  237.     Database= DatabaseManager()
  238.     Versions= VersionManager()
  239.     DebugInfo=DebugManager()
  240.  
  241.     manage=manage_main=HTMLFile('cpContents', globals())
  242.     manage_undoForm=HTMLFile('undo', globals())
  243.  
  244.     def version_txt(self):
  245.         if not hasattr(self, '_v_version_txt'):
  246.             self._v_version_txt=version_txt()
  247.                 
  248.         return self._v_version_txt
  249.  
  250.     def sys_version(self): return sys.version
  251.     def sys_platform(self): return sys.platform
  252.  
  253.     _objects=(
  254.         {'id': 'Database',
  255.          'meta_type': Database.meta_type},
  256.         {'id': 'Versions',
  257.          'meta_type': Versions.meta_type},
  258.         {'id': 'Products',
  259.          'meta_type': 'Product Management'},
  260.         {'id': 'DebugInfo',
  261.          'meta_type': DebugInfo.meta_type},
  262.         )
  263.  
  264.     manage_options=(
  265.         (
  266.         {'label':'Contents', 'action':'manage_main',
  267.          'help':('OFSP','Control-Panel_Contents.stx')},
  268.         )
  269.         +Undo.UndoSupport.manage_options
  270.         )
  271.     
  272.     id        ='Control_Panel'
  273.     name=title='Control Panel'
  274.     meta_type ='Control Panel'
  275.     icon='p_/ControlPanel_icon'
  276.  
  277.     process_id=os.getpid()
  278.     process_start=int(time.time())
  279.  
  280.     # Disable some inappropriate operations
  281.     manage_addObject=None
  282.     manage_delObjects=None
  283.     manage_addProperty=None
  284.     manage_editProperties=None
  285.     manage_delProperties=None
  286.  
  287.     def __init__(self):
  288.         self.Products=ProductFolder()
  289.  
  290.  
  291. # Note by brian:
  292. #
  293. # This __setstate__ does not seem to work - it creates a new ProductFolder
  294. # and adds it to the CP instance if needed, but the resulting PF does not
  295. # seem to be persistent ;( Rather than spend much time figuring out why,
  296. # I just added a check in Application.open_bobobase to create the PF if
  297. # it is needed (this is where several other b/c checks are done anyway.)
  298. #
  299. #
  300. #    def __setstate__(self, v):
  301. #        ApplicationManager.inheritedAttribute('__setstate__')(self, v)
  302. #        if not hasattr(self, 'Products'):
  303. #            self.Products=ProductFolder()
  304.  
  305.  
  306.     def _canCopy(self, op=0):
  307.         return 0
  308.  
  309.     def _init(self):
  310.         pass
  311.  
  312.     def manage_app(self, URL2):
  313.         """Return to the main management screen"""
  314.         raise 'Redirect', URL2+'/manage'
  315.  
  316.     def process_time(self):
  317.         s=int(time.time())-self.process_start   
  318.         d=int(s/86400)
  319.         s=s-(d*86400)
  320.         h=int(s/3600)
  321.         s=s-(h*3600)
  322.         m=int(s/60)
  323.         s=s-(m*60)      
  324.         d=d and ('%d day%s'  % (d, (d != 1 and 's' or ''))) or ''
  325.         h=h and ('%d hour%s' % (h, (h != 1 and 's' or ''))) or ''
  326.         m=m and ('%d min' % m) or ''
  327.         s='%d sec' % s
  328.         return '%s %s %s %s' % (d, h, m, s)
  329.  
  330.     def thread_get_ident(self): return get_ident()
  331.  
  332.     def db_name(self):
  333.         return self._p_jar.db().getName()
  334.  
  335.     def db_size(self):
  336.         if Globals.DatabaseVersion=='2':
  337.             s=os.stat(self.db_name())[6]
  338.         else:
  339.             s=self._p_jar.db().getSize()
  340.             if type(s) is type(''): return s
  341.  
  342.         if s >= 1048576.0: return '%.1fM' % (s/1048576.0)
  343.         return '%.1fK' % (s/1024.0)
  344.  
  345.  
  346.  
  347.     if hasattr(sys, 'ZMANAGED'):
  348.         
  349.         manage_restartable=1
  350.         def manage_restart(self, URL1):
  351.             """Shut down the application"""
  352.             for db in Globals.opened: db.close()
  353.             raise SystemExit, """<html>
  354.             <head><meta HTTP-EQUIV=REFRESH CONTENT="5; URL=%s/manage_main">
  355.             </head>
  356.             <body>Zope is restarting</body></html>
  357.             """ % URL1
  358.             sys.exit(1)
  359.  
  360.     def manage_shutdown(self):
  361.         """Shut down the application"""
  362.         for db in Globals.opened: db.close()
  363.         sys.exit(0)
  364.  
  365.     def manage_pack(self, days=0, REQUEST=None):
  366.         """Pack the database"""
  367.  
  368.         t=time.time()-days*86400
  369.  
  370.         db=self._p_jar.db()
  371.         t=db.pack(t)
  372.         if REQUEST is not None:
  373.             REQUEST['RESPONSE'].redirect(
  374.                 REQUEST['URL1']+'/manage_workspace')
  375.         return t
  376.  
  377.     def revert_points(self): return ()
  378.  
  379.     def version_list(self):
  380.         # Return a list of currently installed products/versions
  381.         path_join=os.path.join
  382.         isdir=os.path.isdir
  383.         exists=os.path.exists
  384.         strip=string.strip
  385.  
  386.         product_dir=path_join(SOFTWARE_HOME,'Products')
  387.         product_names=os.listdir(product_dir)
  388.         product_names.sort()
  389.         info=[]
  390.         for product_name in product_names:
  391.             package_dir=path_join(product_dir, product_name)
  392.             if not isdir(package_dir):
  393.                 continue
  394.             version_txt=path_join(package_dir, 'version.txt')
  395.             if not exists(version_txt):
  396.                 continue
  397.             file=open(version_txt, 'r')
  398.             data=file.readline()
  399.             file.close()
  400.             info.append(strip(data))
  401.         return info
  402.  
  403.  
  404.     def version_info(self):
  405.         r=[]
  406.         try: db=self._p_jar.db()
  407.         except: raise 'Zope database version error', """
  408.         Sorry, <em>Version management</em> is only supported if you use ZODB 3.
  409.         """
  410.         for v in db.versions():
  411.             if db.versionEmpty(v): continue
  412.             r.append({'id': v})
  413.         return r
  414.  
  415.     def manage_saveVersions(self, versions, REQUEST=None):
  416.         "Commit some versions"
  417.         db=self._p_jar.db()
  418.         for v in versions:
  419.             db.commitVersion(v)
  420.         if REQUEST is not None:
  421.             REQUEST['RESPONSE'].redirect(REQUEST['URL1']+'/manage_main')
  422.  
  423.     def manage_discardVersions(self, versions, REQUEST=None):
  424.         "Discard some versions"
  425.         db=self._p_jar.db()
  426.         for v in versions:
  427.             db.abortVersion(v)
  428.         if REQUEST is not None:
  429.             REQUEST['RESPONSE'].redirect(REQUEST['URL1']+'/manage_main')
  430.             
  431.